package com.wonder.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.vtuzx.core.VtuzxException;
import com.vtuzx.core.bean.dto.VtuzxMap;
import com.vtuzx.core.utils.VtuzxUtil;
import com.wonder.admin.domain.StoreToken;
import com.wonder.admin.domain.SysAdmin;
import com.wonder.admin.mapper.StoreTokenDao;
import com.wonder.admin.mapper.SysAdminDao;
import com.wonder.admin.service.IVtuzxKingdeeService;
import com.wonder.app.domain.PrdIronTray;
import com.wonder.app.domain.Tray;
import com.wonder.app.mapper.PrdIronTrayDao;
import com.wonder.app.mapper.TrayDao;
import com.wonder.bean.kingdee.KingdeeAccount;
import com.wonder.bean.kingdee.VtuzxKingdeeCloudClient;
import com.wonder.common.utils.DateUtils;
import org.bson.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

@Service
public class VtuzxKingdeeServiceImpl implements IVtuzxKingdeeService {
    /** 日志 */
    private static final Logger _logger = LoggerFactory.getLogger(VtuzxKingdeeServiceImpl.class);


    @Autowired
    private StoreTokenDao storeTokenDao;

    @Autowired
    private SysAdminDao sysAdminDao;

    @Autowired
    private IVtuzxKingdeeService vtuzxKingdeeService;

    @Autowired
    private TrayDao trayDao;

    @Autowired
    private PrdIronTrayDao prdIronTrayDao;

    @Override
    public KingdeeAccount getAccount() {
        QueryWrapper<StoreToken> wrapper = new QueryWrapper();
         wrapper.eq("type", "kingdee");
        StoreToken storeToken = storeTokenDao.selectOne(wrapper);
        KingdeeAccount kingdeeAccount = new KingdeeAccount(storeToken.getUrl()
        ,storeToken.getDataCenter(),storeToken.getAccount(),storeToken.getPassword(),storeToken.getLang());

        return kingdeeAccount;
    }




    @Override
    public VtuzxKingdeeCloudClient loginKingdee() throws VtuzxException {
        KingdeeAccount account = getAccount();
        _logger.info("kingdee login account:" + account.getAccount() + ", password:" + account.getPassword());
        return new VtuzxKingdeeCloudClient(account).login();
    }

    @Override
    public VtuzxKingdeeCloudClient loginKingdeeByUser(Long userId) throws VtuzxException {
        KingdeeAccount account = getAccountByUser(userId);
        _logger.info("kingdee login account:" + account.getAccount() + ", password:" + account.getPassword());
        return new VtuzxKingdeeCloudClient(account).login();
    }

    @Override
    public KingdeeAccount getAccountByUser(Long userId) {
        SysAdmin sysAdmin = sysAdminDao.selectById(userId);
        QueryWrapper<StoreToken> wrapper = new QueryWrapper();
        wrapper.eq("type", "kingdee");
        StoreToken storeToken = storeTokenDao.selectOne(wrapper);
        KingdeeAccount kingdeeAccount = new KingdeeAccount(storeToken.getUrl()
                ,storeToken.getDataCenter(),sysAdmin.getKingdee_account(),sysAdmin.getKingdee_password(),storeToken.getLang());

        return kingdeeAccount;
    }

    @Override
    public VtuzxKingdeeCloudClient loginQKingdeeByUser(Long userId) throws VtuzxException {
        KingdeeAccount account = getQAccountByUser(userId);
        _logger.info("Qkingdee login account:" + account.getAccount() + ", password:" + account.getPassword() + ",Qkingdee login account:" + account.getUrl()+",Qkingdee login account:" + account.getDataCenterId());
        return new VtuzxKingdeeCloudClient(account).login();
    }

    @Override
    public KingdeeAccount getQAccountByUser(Long userId) {
        SysAdmin sysAdmin = sysAdminDao.selectById(userId);
        QueryWrapper<StoreToken> wrapper = new QueryWrapper();
        wrapper.eq("type", "Qkingdee");
        StoreToken storeToken = storeTokenDao.selectOne(wrapper);
        KingdeeAccount kingdeeAccount = new KingdeeAccount(storeToken.getUrl()
                ,storeToken.getDataCenter(),sysAdmin.getKingdee_account(),sysAdmin.getKingdee_password(),storeToken.getLang());

        return kingdeeAccount;
    }


    @Override
    public List<VtuzxMap> save(VtuzxKingdeeCloudClient client, String formId, VtuzxMap param) throws Exception {
        return client.save(formId, param);
    }

    @Override
    public List<Map<String,Object>> orderUp(VtuzxKingdeeCloudClient client, String formId, VtuzxMap param) throws Exception {

        return client.orderUp(formId, param);
    }

    @Override
    public List<VtuzxMap> save(VtuzxKingdeeCloudClient client, String formId, Map<String, Object> param) throws Exception {
        VtuzxMap p = new VtuzxMap(param);
        return client.save(formId, p);
    }

    @Override
    public List<VtuzxMap> push(VtuzxKingdeeCloudClient client, String formId, VtuzxMap param) throws Exception {
        return client.push(formId, param);
    }

    @Override
    public List<VtuzxMap> push(VtuzxKingdeeCloudClient client, String formId, Map<String, Object> param) throws Exception {
        VtuzxMap p = new VtuzxMap(param);
        return client.push(formId, p);
    }

    @Override
    public List<VtuzxMap> submit(VtuzxKingdeeCloudClient client, String formId, String orgId, String billNo) throws Exception {
        return client.submit(formId, new VtuzxMap("CreateOrgId", orgId).append("Numbers", billNo));
    }

    @Override
    public List<VtuzxMap> audit(VtuzxKingdeeCloudClient client, String formId, String orgId, String billNo) throws Exception {
        return client.audit(formId, new VtuzxMap("CreateOrgId", orgId).append("Numbers", billNo));
    }

    @Override
    public List<VtuzxMap> unAudit(VtuzxKingdeeCloudClient client, String formId, String orgId, String billNo) throws Exception {
        return client.unAudit(formId, new VtuzxMap("CreateOrgId", orgId).append("Numbers", billNo));
    }

    @Override
    public List<VtuzxMap> audit(VtuzxKingdeeCloudClient client, String formId, String orgId, String billNo, String interationFlags) throws Exception {
        return client.audit(formId, new VtuzxMap("CreateOrgId", orgId).append("Numbers", billNo).append("InterationFlags", interationFlags));
    }

    @Override
    public List<VtuzxMap> toRelease(VtuzxKingdeeCloudClient client, String formId, String status, String orgId, String billNo) throws Exception {
        return client.toRelease(formId, status, new VtuzxMap("CreateOrgId", orgId).append("Numbers", billNo));
    }

    @Override
    public List<VtuzxMap> toRelease(VtuzxKingdeeCloudClient client, String formId, String status, String orgId, String billNo, String interationFlags) throws Exception {
        return client.toRelease(formId, status, new VtuzxMap("CreateOrgId", orgId).append("Numbers", billNo).append("InterationFlags", interationFlags));
    }

    @Override
    public List<VtuzxMap> saveAttachment(VtuzxKingdeeCloudClient client, String type, String fId, String fNumber, String fileId, String fileName, int fileSize, String ext, boolean allowDownload) throws Exception {
        VtuzxMap model = new VtuzxMap();
        model.append("FID", 0);
        model.append("FBILLTYPE", type);
        model.append("FINTERID", fId);
        model.append("FBILLNO", fNumber);
        model.append("FENTRYKEY", " ");
        model.append("FENTRYINTERID", -1);
        model.append("FFILEID", fileId);
        model.append("FFILESTORAGE","1");
        model.append("FATTACHMENTNAME", fileName);
        model.append("FEXTNAME", "." + ext);
        model.append("FATTACHMENTSIZE", new BigDecimal(fileSize).divide(BigDecimal.valueOf(1024), 2, RoundingMode.HALF_UP).doubleValue());
        model.append("FBILLSTATUS", "A");
        model.append("FALIASFILENAME", "");
        model.append("FIsAllowDownLoad", allowDownload);
        model.append("FCREATEMEN", new VtuzxMap("FUSERID", client.get("UserId")));
        model.append("FCREATETIME", VtuzxUtil.formatYmdHmsF(new Date()));
        VtuzxMap param = new VtuzxMap("Creator", "Vtuzx")
                .append("NeedUpDateFields", new ArrayList<>())
                .append("Model", model);
        return client.save("BOS_Attachment", param);
    }

    @Override
    public List<VtuzxMap> query(VtuzxKingdeeCloudClient client, String formId, List<String> fieldList, String cond, String order, int start, int limit) throws Exception {
        List<String> fillFieldList = fieldList == null? new ArrayList<>(): new ArrayList<>(fieldList);
        return client.query(formId, fillFieldList, cond, order, start, limit);
    }

    @Override
    public List<VtuzxMap> batchsave(VtuzxKingdeeCloudClient client, String formId, Map<String, Object> param) throws Exception {
        VtuzxMap p = new VtuzxMap(param);
        return client.batchsave(formId, p);
    }

    @Override
    public List<VtuzxMap> getInventoryBymaterial(Long user_id,String materialNo) throws Exception {
        VtuzxKingdeeCloudClient client = null;
        try {
            client = vtuzxKingdeeService.loginKingdeeByUser(user_id);
        } catch (Exception e){
            throw new RuntimeException("金蝶账号密码错误，请维护");
        }
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("FMaterialId.FNUMBER");//物料编码
        arrayList.add("FMaterialId.FName");//物料名称
        arrayList.add("FMaterialId.FSPECIFICATION");//规格型号(件号)
        arrayList.add("FLot.fname");//批号
        arrayList.add("FBASEQTY");//库存基本数量
        arrayList.add("FStockId.FNUMBER");//仓库编码
        arrayList.add("FStockName");//仓库名称
        arrayList.add("FStockLocId.FF100001");//仓位内码
        arrayList.add("FStockLocId.FF100001.FNUmber");//仓位编码
        arrayList.add("FBaseUnitId.fname");
        arrayList.add("FBaseUnitId");
        List<VtuzxMap> otherQuery = vtuzxKingdeeService.query(client, "STK_Inventory", arrayList,
                String.format("FMaterialId.FNUMBER = '%s' or FMaterialId.FSPECIFICATION = '%s'",materialNo,materialNo), "FID", 0, 0);
        return otherQuery;

    }


    @Override
    public List<VtuzxMap> getInventoryByLocation(Long user_id, String locationNo) throws Exception {
        VtuzxKingdeeCloudClient client = null;
        try {
            client = vtuzxKingdeeService.loginKingdeeByUser(user_id);
        } catch (Exception e){
            throw new RuntimeException("金蝶账号密码错误，请维护");
        }
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("FMaterialId.FNUMBER");//物料编码
        arrayList.add("FMaterialId.FName");//物料名称
        arrayList.add("FMaterialId.FSPECIFICATION");//规格型号(件号)
        arrayList.add("FLot.fname");//批号
        arrayList.add("FBASEQTY");//库存基本数量
        arrayList.add("FStockId.FNUMBER");//仓库编码
        arrayList.add("FStockName");//仓库名称
        arrayList.add("FStockLocId.FF100001");//仓位内码
        arrayList.add("FStockLocId.FF100001.FNUmber");//仓位编码
        arrayList.add("FStockLocId.FF100001.FName");//仓位名称
        arrayList.add("FBaseUnitId.fname");
        arrayList.add("FBaseUnitId.fnumber");
        arrayList.add("FBaseUnitId");
        arrayList.add("FProduceDate");

        String materialNo = "";
        //判断是仓位还是托盘码
        if(locationNo.startsWith("TPTRAY")){//正常托盘
            Tray tray = trayDao.selectOne(new LambdaQueryWrapper<Tray>()
                    .eq(Tray::getFBILLNO, locationNo));
            materialNo = tray.getFMATERIALNUMBER();
        } else if (locationNo.startsWith("IRON") ){//合托后的
            PrdIronTray prdIronTray = prdIronTrayDao.selectOne(new LambdaQueryWrapper<PrdIronTray>()
                    .eq(PrdIronTray::getBillNo, locationNo));
            materialNo = prdIronTray.getMaterialNo();
        }
        List<VtuzxMap> otherQuery = new ArrayList<>();
        if (!VtuzxUtil.isEmpty(materialNo)){
            otherQuery = vtuzxKingdeeService.query(client, "STK_Inventory", arrayList,
                    String.format("FMaterialId.FNUMBER = '%s' and FStockId.FNUMBER = 'CK004' and FBASEQTY > 0",materialNo), "FID", 0, 0);
        } else {
            otherQuery = vtuzxKingdeeService.query(client, "STK_Inventory", arrayList,
                    String.format("FStockLocId.FF100001.FNUmber = '%s' and FStockId.FNUMBER = 'CK004' and FBASEQTY > 0",locationNo), "FID", 0, 0);
        }


        List<VtuzxMap> dataList = new ArrayList<>();
        for (VtuzxMap data : otherQuery){
            String fmaterialnumber = VtuzxUtil.getString(data,"FMaterialId.FNUMBER");
            String fmaterialname = VtuzxUtil.getString(data,"FMaterialId.FName");
            String fspecification = VtuzxUtil.getString(data,"FMaterialId.FSPECIFICATION");
            String flot = VtuzxUtil.getString(data,"FLot.fname");
            String locationno = VtuzxUtil.getString(data,"FStockLocId.FF100001.FNUmber");
            String locationname = VtuzxUtil.getString(data,"FStockLocId.FF100001.FName");
            String stockno = VtuzxUtil.getString(data,"FStockId.FNUMBER");
            String stockname = VtuzxUtil.getString(data,"FStockName");
            String unitname = VtuzxUtil.getString(data,"FBaseUnitId.fname");
            String unitno = VtuzxUtil.getString(data,"FBaseUnitId.fnumber");
            String FProduceDate = VtuzxUtil.getString(data,"FProduceDate");
            Double FBASEQTY = VtuzxUtil.getDouble(data,"FBASEQTY");
            VtuzxMap dataMap = new VtuzxMap();
            dataMap.put("fmaterialnumber",fmaterialnumber);
            dataMap.put("fmaterialname",fmaterialname);
            dataMap.put("itemnumber",fspecification);
            dataMap.put("flot",flot);
            dataMap.put("locationno",locationno);
            dataMap.put("stockno",stockno);
            dataMap.put("stockname",stockname);
            dataMap.put("fqty",FBASEQTY);
            dataMap.put("locationname",locationname);
            dataMap.put("funitname",unitname);
            dataMap.put("funitid",unitno);
            Date createDate = DateUtils.strToDate(FProduceDate,"yyyy-MM-dd'T'HH:mm:ss");
            dataMap.put("productiondate",DateUtils.dateToStr(createDate,"yyyy-MM-dd HH:mm:ss"));//生产日期str类型(T)
            dataList.add(dataMap);

        }

        return dataList;
    }

    @Override
    public List<VtuzxMap> getInventoryBymaterialPackage(Long user_id, String materialNo) throws Exception {
        VtuzxKingdeeCloudClient client = null;
        try {
            client = vtuzxKingdeeService.loginKingdeeByUser(user_id);
        } catch (Exception e){
            throw new RuntimeException("金蝶账号密码错误，请维护");
        }
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("FMaterialId.FNUMBER");//物料编码
        arrayList.add("FMaterialId.FName");//物料名称
        arrayList.add("FMaterialId.FSPECIFICATION");//规格型号(件号)
        arrayList.add("FLot.fname");//批号
        arrayList.add("FBASEQTY");//库存基本数量
        arrayList.add("FStockId.FNUMBER");//仓库编码
        arrayList.add("FStockName");//仓库名称
        arrayList.add("FStockLocId.FF100001");//仓位内码
        arrayList.add("FStockLocId.FF100001.FNUmber");//仓位编码
        arrayList.add("FBaseUnitId.fname");
        arrayList.add("FBaseUnitId");
        arrayList.add("FProduceDate");
        List<VtuzxMap> otherQuery = vtuzxKingdeeService.query(client, "STK_Inventory", arrayList,
                String.format("FMaterialId.FNUMBER = '%s' and FStockId.FNUMBER = 'CK020' and FBASEQTY > 0",materialNo), "FProduceDate", 0, 0);
        return otherQuery;
    }

    /**
     * 查询金蝶即时库存
     * @param user_id
     * @param materialNoList
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, Object> getInventoryBymaterialList(Long user_id, List<String> materialNoList) throws Exception {
        VtuzxKingdeeCloudClient client = null;
        try {
            client = vtuzxKingdeeService.loginKingdeeByUser(user_id);
        } catch (Exception e){
            throw new RuntimeException("金蝶账号密码错误，请维护");
        }
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("FMaterialId.FNUMBER");//物料编码
        arrayList.add("FBASEQTY");//库存基本数量
        String materialNoCond = org.springframework.util.StringUtils.collectionToDelimitedString(materialNoList, ",", "'", "'");
        List<VtuzxMap> otherQuery = vtuzxKingdeeService.query(client, "STK_Inventory", arrayList,
                String.format("FMaterialId.FNUMBER in (%s) and FStockId.FNUMBER = 'CK020' and FBASEQTY > 0",materialNoCond), "FProduceDate", 0, 0);
        Map<String,Object> queryMap = new HashMap<>();//key:物料 val:数量
        for (VtuzxMap data : otherQuery){
            String materialNo = VtuzxUtil.getString(data,"FMaterialId.FNUMBER");
            double baseQty = VtuzxUtil.getDouble(data,"FBASEQTY");
            double count = VtuzxUtil.getDouble(queryMap,materialNo);
            queryMap.put(materialNo,baseQty + count);

        }

        return queryMap;
    }

    /**
     * 查询工序计划的状态
     * @param user_id
     * @param moNoList
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, Object> getOrderStatus(Long user_id, List<String> moNoList) throws Exception {
        VtuzxKingdeeCloudClient client = null;
        try {
            client = vtuzxKingdeeService.loginKingdeeByUser(user_id);
        } catch (Exception e){
            throw new RuntimeException("金蝶账号密码错误，请维护");
        }
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("FOperStatus");//分录状态
        arrayList.add("FOperQty");//计划数量
        arrayList.add("FDocumentStatus");//单据状态
        arrayList.add("FMONumber");//生产订单编号
        String materialNoCond = org.springframework.util.StringUtils.collectionToDelimitedString(moNoList, ",", "'", "'");
        List<VtuzxMap> otherQuery = vtuzxKingdeeService.query(client, "SFC_OperationPlanning", arrayList,
                String.format("FMONumber in (%s)",materialNoCond), "FModifyDate", 0, 0);
        Map<String,Object> orderMap = new HashMap<>();//key:生产订单号  val:单据状态，分录状态
        if (!VtuzxUtil.isEmpty(otherQuery)){
            for (VtuzxMap data : otherQuery){
                String FMONumber = VtuzxUtil.getString(data,"FMONumber");
                orderMap.put(FMONumber, data);
            }
        }


        return orderMap;
    }



    /**
     * 查询生产订单的订单数量
     * @param user_id
     * @param moNoList
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, Object> getMoQty(Long user_id, List<String> moNoList) throws Exception {
        VtuzxKingdeeCloudClient client = null;
        try {
            client = vtuzxKingdeeService.loginKingdeeByUser(user_id);
        } catch (Exception e){
            throw new RuntimeException("金蝶账号密码错误，请维护");
        }
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("FQty");//数量
        arrayList.add("FBillNo");//单据编号
        String materialNoCond = org.springframework.util.StringUtils.collectionToDelimitedString(moNoList, ",", "'", "'");
        List<VtuzxMap> otherQuery = vtuzxKingdeeService.query(client, "PRD_MO", arrayList,
                String.format("FBillNo in (%s)",materialNoCond), "FCreateDate", 0, 0);
        Map<String,Object> orderMap = new HashMap<>();//key:生产订单号  val:单据状态，分录状态
        if (!VtuzxUtil.isEmpty(otherQuery)){
            for (VtuzxMap data : otherQuery){
                String FBillNo = VtuzxUtil.getString(data,"FBillNo");
                Double FQty = VtuzxUtil.getDouble(data,"FQty");
                orderMap.put(FBillNo, FQty);
            }
        }


        return orderMap;
    }


}
